#pragma once
#include "main.h"
#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

#define MSG_SIZE sizeof(int) // 每条消息大小，这里用 int
#define MSG_COUNT 10         // 队列能存的消息个数

#define RX_BUF_SIZE 32
#define RX_TIMEOUT 10 // ms
K_MEM_SLAB_DEFINE(uart_slab, RX_BUF_SIZE, 500, 4);

#define AY_BUF_COUNT 5
#define AY_BUF_SIZE 4096
int current_buf_index = 0;
uint8_t *current_buf = NULL;
uint8_t ay_rx_buf[AY_BUF_COUNT][AY_BUF_SIZE];

const struct device *uart2 = DEVICE_DT_GET(DT_NODELABEL(uart22));
// struct uart_data_t packet = {
//     .data = k_malloc(len),
//     .len = len,
// };
struct uart_data_t
{
    uint8_t *data;
    size_t len;
};

K_MSGQ_DEFINE(rx_queue, sizeof(struct uart_data_t), 160, 4);

static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
    struct device *uart = (struct device *)user_data;
    int err;

    //  LOG_INF("RX done %d bytes", evt->type);
    // int  send = evt->type;
    switch (evt->type)
    {
        // case UART_TX_DONE:
        //     LOG_INF("TX done %d bytes", evt->data.tx.len);
        //     k_sem_give(&tx_done);
        // 	break;

        // case UART_TX_ABORTED:
        //     LOG_WRN("TX aborted");
        //     k_sem_give(&tx_done);
        // 	break;

    case UART_RX_RDY:
    {
        uint8_t *p = &(evt->data.rx.buf[evt->data.rx.offset]);
        size_t len = evt->data.rx.len;
        // uart_tx(uart2, p, len, SYS_FOREVER_MS);

        // LOG_INF("RX count %d", rx_count++);

        struct uart_data_t packet = {
            .data = current_buf,
            .len = len,
        };

        // if( NULL == packet.data){
        //     LOG_ERR("Failed to alloc memory for RX packet!!!");
        //     return;
        // }

        // if the RX buffer is full, it will be free after the `uart_callback` return.
        // so the data should be copy here.

        memcpy(packet.data, p, len);

        err = k_msgq_put(&rx_queue, &packet, K_NO_WAIT);
        if (err)
        {

            //     int  send = 0x88;
            //   LOG_ERR("Failed to put packet to RX queue, freeing memory");
            //     k_free(packet.data);
        }
        else
        {
            // LOG_INF("RX %d bytes copied", len);
        }

        break;
    }

    case UART_RX_BUF_REQUEST: // 请求下一次串口接收缓冲区
    {
        uint8_t *buf;
        // LOG_INF("RX buffer request");
        //	err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
        //   __ASSERT(err == 0, "Failed to allocate slab\n");
        // 设置下一次的缓冲区

        current_buf = ay_rx_buf[current_buf_index % AY_BUF_COUNT];
        current_buf_index++;
        err = uart_rx_buf_rsp(uart, current_buf, AY_BUF_SIZE);

        //__ASSERT(err == 0, "Failed to provide new buffer\n");
        break;
    }

    case UART_RX_BUF_RELEASED:
    {

        break;
    }

        // 缓冲区用完了  释放掉
        //  LOG_INF("RX buffer released");
        //  k_mem_slab_free(&uart_slab, (void *)evt->data.rx_buf.buf);

    case UART_RX_DISABLED:
    {
        LOG_INF("RX disable,reason:%d", evt->data);
        break;
    }

    case UART_RX_STOPPED:
    {

        LOG_INF("RX stop,reason:%d", evt->data.rx_stop.reason);
        LOG_INF("重启串口接收");
        set_errcode(-2);
        uart_rx_enable(uart2, ay_rx_buf[current_buf_index % AY_BUF_COUNT], AY_BUF_SIZE, SYS_FOREVER_US);
        current_buf_index++;
        //    const char *buf_name = "UART停止";
        break;
    }

    //  uint8_t *buf;
    //     //分配内存到buf
    //     err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    //     __ASSERT(err == 0, "Failed to alloc slab");
    //     // for the UARTE that have "frame-timeout-supported" property,
    //     // the RX_INACTIVE_TIMEOUT_US doesn't take effect if it is bigger than max FRAMETIMEOUT of UARTE.
    //     // For example, nRF54L15
    //     //SYS_FOREVER_US
    //     err = uart_rx_enable(uart, buf, RX_BUF_SIZE,500);
    break;
    }
}

void uart_irq(const struct device *dev, void *user_data)
{

    //     struct uart_data_t packet = {
    //     .data = (uint8_t *)k_malloc(len),
    //     .len = len,
    // };
}

void rx_uart_init(void)
{

    k_thread_name_set(k_current_get(), "uart_init");

    uint8_t *buf; // 创建一个临时变量,用于获取当前uart_slab 内存池的一块

    struct uart_config cfg = {
        .baudrate = 57600,
        .parity = UART_CFG_PARITY_NONE,
        .stop_bits = UART_CFG_STOP_BITS_1,
        .data_bits = UART_CFG_DATA_BITS_8,
        .flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
    };

    int rc = uart_configure(uart2, &cfg);
    if (rc)
    {
        printk("Could not configure device %s, rc=%d\n", uart2->name, rc);
        return;
    }
    // 设置回调
    rc = uart_callback_set(uart2, uart_cb, (void *)uart2);
    //   rc = uart_irq_callback_set(uart2, uart_cb);
    // uart_irq_rx_enable(uart2);
    //	__ASSERT(rc == 0, "Failed to set callback");

    // 分配内存到buf
    //   rc = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    // 	__ASSERT(rc == 0, "Failed to alloc slab");
    // for the UARTE that have "frame-timeout-supported" property,
    // the RX_INACTIVE_TIMEOUT_US doesn't take effect if it is bigger than max FRAMETIMEOUT of UARTE.
    // For example, nRF54L15
    // SYS_FOREVER_US
    current_buf = ay_rx_buf[current_buf_index % AY_BUF_COUNT];
    current_buf_index++;
    rc = uart_rx_enable(uart2, current_buf, AY_BUF_SIZE, SYS_FOREVER_US);
    __ASSERT(rc == 0, "Failed to enable rx");
    /* 发送测试字符串 */
    uart_tx(uart2, (uint8_t *)"Hello DMA!\n", 11, SYS_FOREVER_MS);
}

#include <iomanip>

// void thread_info_cb(const struct k_thread *thread, void *user_data) {
//     const char *name = k_thread_name_get((k_tid_t)thread);
//     struct k_thread_stack_info info;

//     if (IS_ENABLED(CONFIG_THREAD_STACK_INFO) &&
//         k_thread_stack_info_get((k_tid_t)thread, &info) == 0) {
//         size_t unused = k_thread_stack_space_get((k_tid_t)thread);
//         size_t total  = info.size;

//         printk("Thread %s (%p) pri %d stack %zu/%zu used\n",
//                name ? name : "unknown", thread,
//                k_thread_priority_get((k_tid_t)thread),
//                total - unused, total);
//     } else {
//         printk("Thread %s (%p)\n", name ? name : "unknown", thread);
//     }
// }

// void print_all_threads(void) {
//     k_thread_foreach(thread_info_cb, NULL);
// }

#include <zephyr/sys/mem_stats.h>
// extern struct sys_heap _system_heap;
extern struct k_heap _system_heap;

void print_heap_info()
{

    int ret;
    struct sys_memory_stats heap_stats;
    size_t free_stack;

    ret = k_thread_stack_space_get(k_current_get(), &free_stack);
    if (ret < 0)
    {
        printk("Failed to get stack stats\r\n");
    }
    else
    {
        printk("Stack | Free: %u bytes\r\n", free_stack);
    }
    ret = sys_heap_runtime_stats_get(&_system_heap.heap, &heap_stats);
    if (ret < 0)
    {
        printk("Failed to get heap stats\r\n");
    }
    else
    {
        printk("Heap  | Free: %u bytes, Allocated: %u bytes ,max :%u bytes\r\n",
               heap_stats.free_bytes,
               heap_stats.allocated_bytes,
               heap_stats.max_allocated_bytes);
    }
}

char data_str[26000] = {0};
// #include "ay_ble.hpp"
extern void ble_send_data(const char *str);
extern void ble_send_data_hex(uint8_t *data);
void consumer(void)
{

    try
    {
        k_thread_name_set(k_current_get(), "uart_consumer");

        unsigned char value;
        int err;
        struct uart_data_t packet = {0};
        int count_rx = 0;

        string heart_v_str_data; // 心率值

        uint8_t heart_count; // 心跳次数

        uint8_t tmp_buf[4096];

        while (1)
        {
            err = k_msgq_get(&rx_queue, &packet, K_FOREVER);
            if (err)
            {
                LOG_ERR("Failed to get packet from RX queue");
                continue;
            }

            //  LOG_INF("data size before %d", data.size());
             memcpy(tmp_buf, packet.data, packet.len);
            if (dev.dev_mode == 1) //如果是蓝牙模式
            {
               

                ble_send_data_hex(tmp_buf);

                continue;
            }

            // 打印标头和数据
            //   cout << "收到数据: "<<endl;
            //     for(int i=0;i<64;i++)cout <<std::setfill('0') << std::setw(2)<< i <<" ";
            //     cout << endl;

            // for (int i = 0; i < packet.len; i++)
            // {
            //     // 添加宽度2位16进制输出，不足补0
            //     // cout<<std::setfill('0') << std::setw(2);
            //     cout << std::setfill('0') << std::setw(2) << std::hex << (int)tmp_buf[i] << " ";
            //     if ((i + 1) % 64 == 0)
            //     {
            //         cout << endl;
            //     }
            // }
            // cout << endl;
            LOG_INF("接收到数据数量: %d", packet.len);

            // LOG_INF("heart_v_str_data size before %d", heart_v_str_data.size());
            // print_heap_info();
            count_rx++;

            int max_len = 4096 - 8;
            char value_str[6] = {0};
            for (int i = 0; i < max_len; i++)
            {
                if (tmp_buf[i] == 0xAA && tmp_buf[i + 1] == 0xAA)
                {
                    if (tmp_buf[i + 2] == 0x04)
                    {
                        uint16_t heart_value = (tmp_buf[i + 5] << 8) | tmp_buf[i + 6];
                        snprintf(value_str, sizeof(value_str), "%04X,", heart_value); // "1234"（大写补零）
                        strcat(data_str, value_str);

                        // heart_v_str_data += uint16_to_hex_manual(heart_value, true);

                        continue;
                    }
                    else if (tmp_buf[i + 2] == 0x12)
                    {

                        heart_count = tmp_buf[i + 6];
                    }
                }
            }

             LOG_INF("第%d次 ,获取心率数据数量: %d", count_rx, strlen(data_str));

            //  LOG_INF("心跳次数: %d", heart_count);
            // 每10秒添加一次数据

            if (count_rx % 100 == 0)
            {
                dev.current_file_name = "/SD:/" + to_string(dev.dev_count) + "_" + to_string(k_uptime_get()) + ".csv";
            }
            if (count_rx % 10 == 0)
            {
                // LOG_INF("当前数据是: \n%s", heart_v_str_data.c_str());
                //   cout<< "内容:" << heart_v_str_data << endl;
                if (count_rx % 100 == 0)
                {
                    cout << "创建文件:" << dev.current_file_name << endl;
                    strcat(data_str, "\n");

                    fs->write_file_char(dev.current_file_name.c_str(), data_str, 1);
                }
                else
                {
                    cout << "追加文件:" << dev.current_file_name << endl;

                    //  heart_v_str_data = "\n" + heart_v_str_data; 

                    strcat(data_str, "\n");
                    fs->write_file_char(dev.current_file_name.c_str(), data_str, 1);
                }
                memset(data_str, 0, sizeof(data_str));
            }

            heart_count = 0;
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << "报错:" << e.what() << '\n';
    }
}
K_THREAD_DEFINE(consumer_id, 8182, consumer, NULL, NULL, NULL, 5, 0, 0);

/////////////////////////////////////////////新uart
